local skynet = require "skynet"
local socket = require "socket"
local CMD = require "main_proto"
local CEN = require "center_proto"
local Sraw = require "stable.raw"
local lobby = require "lobbysql"
Sraw.init()
require "skynet.manager"

local bufferrw = require "buffrw"
local buffwrite = bufferrw.BuffWrite
local buffread  = bufferrw.BuffRead

local Manager
local playerList
local Login = {}

local function SendData(addr,msg)
    skynet.send(math.floor(addr),"lua","send_data",msg)
end

local function NotifyUserLoginSucess(player)
    local msg = string.pack(">I2>I2<I4I4", --登陆成功要发送验证消息去网关
                    CEN.Main_ClientToSvr_NetGate,CEN.Sub_ClientToGate_LoginSuccess,
                    player.nPlayerId,tonumber(skynet.getenv("game_id"))
                    )
    SendData(player.nAgentAddr,msg)
end

function Login.Init(playerlist)
    playerList = playerlist
end

function Login.OnUserLoginReq(smsg, agent_addr,client_addr)
    local BuffRead = buffread.new(smsg)
    BuffRead:proto()
    local play_id   = BuffRead:int4()
    local sex       = BuffRead:int4()
    local logintype = BuffRead:int4()
    local nickname  = BuffRead:str(64)
    local url       = BuffRead:str(192)
    local password  = BuffRead:str(32)
    
    local player = Sraw.get(playerList,tostring(play_id))

    if player and player.nRoomAddr>0 then 
        --断线重连登录
        player.nAgentAddr = agent_addr
        player.szIp = client_addr
        skynet.error("用户断线返回 player_id",play_id,"",player.nRoomAddr)
        local BuffWrite = buffwrite.new()
        url = string.sub(url,1,128)
        BuffWrite:proto(300, 2006)
        BuffWrite:int4(play_id)
        BuffWrite:int4(player.nDiamond)
        BuffWrite:int8(player.llJinBi)
        BuffWrite:int4(player.nScore)
        BuffWrite:int4(sex)
        BuffWrite:int4(logintype)
        BuffWrite:str(player.szName, 64)
        BuffWrite:str(player.szIp, 32)
        BuffWrite:int4(player.nExternCode)
        BuffWrite:str(player.szSign, 128)
        BuffWrite:str(url, 128)
        BuffWrite:int4(player.nGoldRankPos)
        BuffWrite:int8(player.llExGoldCount)
        BuffWrite:int4(player.nRoomId)
        skynet.send(agent_addr, "lua", "send_data", BuffWrite.buff)
        NotifyUserLoginSucess(player)
        return play_id, true,0
    else
        local result=skynet.call(skynet.localname(".sql"), "lua", "OnUserLoginReq", play_id, sex, logintype, nickname, url, password, client_addr)
        if result.bSucc == 1 then
            local bhaveUser = true
            if not player then
                player = Sraw.create()
                bhaveUser = false
            end

            player.nPlayerId = play_id
            player.szPass = password
            player.szName = nickname
            player.nSex = sex
            player.szHeadUrl = result.szHeadUrl
            player.szSign = result.szSign or ""
            url = string.sub(url,1,128)
            player.szIp = client_addr
            
            player.nDiamond = result.nDiamond
            player.llJinBi = result.llJinBi
            
            player.nLoginType = logintype
            player.nScore = result.nScore

            player.nGoldRankPos = result.nGoldRankPos
            player.llExGoldCount = result.llExGoldCount
            
            player.nAgentAddr = agent_addr
            player.nRoomId = 0
            player.nRoomAddr = 0 

            player.nExternCode = result.nExternCode
            player.nStat = 2
            
            if not bhaveUser then
                Sraw.set(playerList,tostring(play_id),player)
            end

            local BuffWrite = buffwrite.new()
            BuffWrite:proto(300, 2003)
            BuffWrite:int4(play_id)
            BuffWrite:int4(player.nDiamond)
            BuffWrite:int8(player.llJinBi)
            BuffWrite:int4(player.nScore)
            BuffWrite:int4(sex)
            BuffWrite:int4(logintype)
            BuffWrite:str(player.szName, 64)
            BuffWrite:str(player.szIp, 32)
            BuffWrite:str("1", 32)
            BuffWrite:int4(player.nExternCode)
            BuffWrite:str(player.szSign, 128)
            BuffWrite:str(url, 128)
            BuffWrite:int4(player.nGoldRankPos)
            BuffWrite:int8(player.llExGoldCount)
            skynet.send(agent_addr, "lua", "send_data", BuffWrite.buff)
            NotifyUserLoginSucess(player)
            if result.nFirstLogin == 1 then
                local msg = string.pack(">I2>I2c96",CMD.Main_ClientAndGameSvr_UserModle, CMD.Sub_GameSvrToClient_UserModle_HingMsg,"今首次登陆,送1000老友豆")
                SendData(player.nAgentAddr,msg)
                lobby.AddOrSubPlayerJinBi(player,1000,"今日首次登陆")
                lobby.OnUserUpdateInfo(player)
            end

            return play_id, true
        else
            skynet.error("db login account error", result.szErrMsg)
            return nil, false
        end        
    end
end

function Login.OnUserCreateReq(smsg, agent_addr,client_addr)
    
    local BuffRead = buffread.new(smsg)
    BuffRead:proto()
    local sex       = BuffRead:int4()
    local logintype = BuffRead:int4()
    local nickname  = BuffRead:str(64)
    local url       = BuffRead:str(192)
    local password  = BuffRead:str(32)
    local openid    = BuffRead:str(64)
    local result = skynet.call(skynet.localname(".sql"),"lua","OnUserCreateReq",sex,logintype,nickname,url,password,client_addr,openid)
    if result.bSucc == 1 then
        local player = Sraw.create()
        player.nPlayerId = math.floor(result.nPlayerId)
        player.nSex = sex
        player.nLoginType = logintype
        player.szName = nickname
        player.szHeadUrl = url
        player.szPass = password
        player.nAgentAddr = agent_addr
        player.nScore = result.nScore
        player.llJinBi = result.llJinBi
        player.nDiamond = result.nDiamond
        player.szSign = result.szSign or  ""
        player.szIp = client_addr
        player.nStat = 2
        player.nRoomId = 0
        player.nRoomAddr = 0 
        url = ""
        player.nGoldRankPos = 0
        player.llExGoldCount = 0
        player.nExternCode = 0
        Sraw.set(playerList,tostring(math.floor(result.nPlayerId)),player)

        local BuffWrite = buffwrite.new()
        BuffWrite:proto(300, 2001)       
        BuffWrite:int4(player.nPlayerId)
        BuffWrite:int4(player.nDiamond)
        BuffWrite:int8(player.llJinBi)
        BuffWrite:int4(player.nScore)
        BuffWrite:int4(player.nSex)
        BuffWrite:int4(player.nLoginType)
        BuffWrite:str(player.szName, 64)
        BuffWrite:str(player.szPass, 32)
        BuffWrite:str(player.szIp, 32)
        BuffWrite:int4(result.nExternCode)
        BuffWrite:str(player.szSign, 128)
        BuffWrite:int4(result.nGoldRankPos)
        BuffWrite:int8(result.llExGoldCount)
        skynet.send(agent_addr,"lua","send_data",BuffWrite.buff)
        
        NotifyUserLoginSucess(player)
        return math.floor(player.nPlayerId), true
    else
        skynet.error("db create account error ",result.szErrMsg)
        return nil, false
    end
    
end


skynet.start(function()
    skynet.error("login server start...")
	skynet.dispatch("lua", function(_,_, command, ...)
		local f = Login[command]
        if f then
		  skynet.ret(skynet.pack(f(...)))
        end
	end)
    skynet.register ".login"
    
    math.randomseed(os.time())
end)
